<?php

namespace Kangcg\Application\Http;

class HttpRequestSetopts
{
    const METHOD_POST = 'POST';
    const METHOD_GET = 'GET';

    public function __construct()
    {
        $this->_setopts = [];
        $this->_headers = [];
    }

    public array $sslOpts = [
        CURLOPT_SSL_VERIFYPEER => false, // 对认证证书来源的检查
        CURLOPT_SSL_VERIFYHOST => false, // 从证书中检查SSL加密算法是否存在
        CURLOPT_SSLVERSION => true, //CURL_SSLVERSION_TLSv1
    ];

    //通用头部
    public array $commonOpts = [
        CURLOPT_HEADER => 0, // 显示返回的Header区域内容
        CURLOPT_RETURNTRANSFER => 1, // 获取的信息以文件流的形式返回
        CURLOPT_FOLLOWLOCATION => true, // 使用自动跳转
        CURLOPT_AUTOREFERER => true, //自动设置Referer
        CURLOPT_TIMEOUT => 10,// 设置超时限制防止死循环
    ];

    public function getSetopts(): array
    {
        $setopts = $this->_setopts;
        if (count($this->_headers)) {
            $setopts[CURLOPT_HTTPHEADER] = $this->_headers;
        }

        return $setopts;
    }

    /**
     * 使用头部
     * @return $this
     */
    public function useUseCommon(): self
    {
        return $this->setOptsValues($this->commonOpts);
    }

    /**
     * 模拟真实客户端头部请求
     * @return $this
     */
    public function useSimulateHeader(): self
    {
        $ip_long = [
            ['607649792', '608174079'], //36.56.0.0-36.63.255.255
            ['1038614528', '1039007743'], //61.232.0.0-61.237.255.255
            ['1783627776', '1784676351'], //106.80.0.0-106.95.255.255
            ['2035023872', '2035154943'], //121.76.0.0-121.77.255.255
            ['2078801920', '2079064063'], //123.232.0.0-123.235.255.255
            ['-1950089216', '-1948778497'], //139.196.0.0-139.215.255.255
            ['-1425539072', '-1425014785'], //171.8.0.0-171.15.255.255
            ['-1236271104', '-1235419137'], //182.80.0.0-182.92.255.255
            ['-770113536', '-768606209'], //210.25.0.0-210.47.255.255
            ['-569376768', '-564133889'], //222.16.0.0-222.95.255.255
        ];

        $rand_key = mt_rand(0, 9);
        $ip = long2ip(mt_rand($ip_long[$rand_key][0], $ip_long[$rand_key][1]));
        $header = [
            "Connection: Keep-Alive",
            "Accept: text/html, application/xhtml+xml,
             */*",
            "Pragma: no-cache",
            "Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.3",
            "User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)", 'CLIENT-IP:' . $ip, 'X-FORWARDED-FOR:' . $ip
        ];

        $this->setHeader($header);
        return $this;
    }

    /**
     * 设置单个CURL的 setopts
     * @param int $option
     * @param string $value
     * @return $this
     */
    public function setOptsValue($option, $value): self
    {
        $this->_setopts[$option] = $value;
        return $this;
    }

    /**
     * 设置多个
     * @param array $options
     * @return $this
     */
    public function setOptsValues(array $options): self
    {
        $this->_setopts = $this->_setopts + $options;
        return $this;
    }

    /**
     * 设置Ssl的文件地址
     * @param string $sslCertPath 路径
     * @param string $sslKeyPath 路径
     * @param string $sslType ssl文件类型
     * @return $this
     */
    public function setSslCert($sslCertPath, $sslKeyPath, $sslType = 'PEM'): self
    {
        $this->setoptsValue(CURLOPT_SSLCERTTYPE, $sslType);
        $this->setoptsValue(CURLOPT_SSLCERT, realpath('./' . $sslCertPath));
        $this->setoptsValue(CURLOPT_SSLKEY, realpath('./' . $sslKeyPath));
        return $this;
    }

    /**
     * 设置Header头部
     * @param array $header ['Content-Type' => 'application/x-www-form-urlencoded']
     * @param bool $isAppend 是否追加
     * @return $this
     */
    public function setHeader($header = [], bool $isAppend = true): self
    {
        if ($isAppend === false) {
            $this->_headers[] = [];
        }

        foreach ($header as $k => $v) {
            $this->_headers[] = is_string($k) ? sprintf('%s:%s', $k, $v) : $v;
        }

        return $this;
    }


    /**
     * 模拟登录 保存cookie信息
     * @param string $filePath 保存cookie的文件地址
     * @return $this
     */
    public function setSaveCookieParh(string $filePath): self
    {
        $this->setoptsValue(CURLOPT_COOKIEJAR, $filePath);
        return $this;
    }

    /**
     * 使用cookie信息登录
     * @param string $filePath 保存cookie的文件地址
     * @return $this
     */
    public function setUseCookieParh(string $filePath): self
    {
        $this->setoptsValue(CURLOPT_COOKIEFILE, $filePath);
        return $this;
    }

    public function setSslFalse(array $opts): self
    {
        $this->_setopts = $opts;
        return $this;
    }

    /**
     * 获取CURL 请求模式
     * @param string $url
     * @param string $method
     * @param string|array $data
     * @return mixed
     */
    public function setUrlSetopts(string $url, string $method, mixed $data): self
    {
        $url = trim($url, '?');
        $this->_setopts[CURLOPT_URL] = $url;
        if (strpos($url, 'https:') === 0) {
            $this->setOptsValues($this->sslOpts);
        }

        switch ($method) {
            case self::METHOD_POST :
                $this->setOptsValues([
                    CURLOPT_POST => true,
                    CURLOPT_POSTFIELDS => $data
                ]);
                break;
        }

        return $this;
    }

    private array $_setopts = [];
    private array $_headers = [];
}
